package org.activequant.tradesystem.ib;

import org.activequant.broker.IBroker;
import org.activequant.broker.ib.IBBroker;
import org.activequant.container.ITradeSystemContext;
import org.activequant.container.ITradeSystemContextThread;
import org.activequant.container.context.SpringTradeSystemContext;
import org.activequant.container.services.ITimeStampService;
import org.activequant.core.domainmodel.account.BrokerAccount;
import org.activequant.core.types.TimeStamp;
import org.activequant.data.retrieval.ICandleSeriesSource;
import org.activequant.data.retrieval.ICandleSubscriptionSource;
import org.activequant.data.retrieval.IMarketDepthEventSubscriptionSource;
import org.activequant.data.retrieval.IMarketScanChangeSubscriptionSource;
import org.activequant.data.retrieval.IMarketScanSubscriptionSource;
import org.activequant.data.retrieval.IQuoteSeriesSource;
import org.activequant.data.retrieval.IQuoteSubscriptionSource;
import org.activequant.data.retrieval.ITickerNewsSeriesSource;
import org.activequant.data.retrieval.ITickerNewsSubscriptionSource;
import org.activequant.data.retrieval.ITradeIndicationSubscriptionSource;
import org.activequant.data.retrieval.ib.IBCandleSeriesSource;
import org.activequant.data.retrieval.ib.IBCandleSource;
import org.activequant.data.retrieval.ib.IBContractDetailsSource;
import org.activequant.data.retrieval.ib.IBMarketDepthEventSource;
import org.activequant.data.retrieval.ib.IBQuoteSeriesSource;
import org.activequant.data.retrieval.ib.IBQuoteSource;
import org.activequant.data.retrieval.ib.IBTradeIndicationSource;
import org.activequant.util.ib.IBTwsConnection;
import org.activequant.util.ib.marketscanners.IBMarketScanChangeSource;
import org.activequant.util.ib.marketscanners.IBMarketScanSource;
import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import org.tradesystem.tickernews.RSSTickerNewsSeriesSource;
import org.tradesystem.tickernews.RSSTickerNewsSource;

import com.ib.algokit.ib.IBPortfolioManagingBroker;
/**
 * Configuration annotated class. For use with IB.
 * @author Dimitar
 *
 */
@Configuration
public class LiveContextConfig {
	/**
	 * private final String IB_HOST     = "127.0.0.1";
	 */
	private final String IB_HOST     = "127.0.0.1";
	/**
	 * private final int    IB_PORT     = 7496;
	 */
	private final int    IB_PORT     = 7496;
	/**
	 * private final int    IB_CLIENTID = 0;
	 */
	private final int    IB_CLIENTID = 0;
	/**
	 * Bean<br/>
	 * Creates and returns an IBTwsConnection already connected to IB
	 * @return
	 */
	@Bean
	public IBTwsConnection ibConnection() {
		IBTwsConnection connection = new IBTwsConnection(IB_HOST, IB_PORT, IB_CLIENTID);
		connection.connect();
		connection.start();//this is to start flushing expired historical requests
		return connection;
	}
	
	@Bean
	public BrokerAccount brokerAccount() {
		BrokerAccount brokerAccount = new BrokerAccount();
		return brokerAccount;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBBroker ready to talk to IB
	 * @return
	 */
	@Bean
	public IBroker broker() {
		//IBBroker broker = new IBBroker(ibConnection());
		IBBroker broker = new IBPortfolioManagingBroker(brokerAccount(), ibConnection());
		return broker;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBQuoteSource ready to subscribe for real-time Quotes from IB
	 * @return
	 */
	@Bean
	public IQuoteSubscriptionSource quoteSubscriptionSource() {
		IBQuoteSource source = new IBQuoteSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBTradeIndicationSource ready to subscribe for real-time TradeIndications from IB
	 * @return
	 */
	@Bean
	public ITradeIndicationSubscriptionSource tradeIndicationSubscriptionSource() {
		IBTradeIndicationSource source = new IBTradeIndicationSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBCandleSource ready to subscribe for real-time Candles from IB
	 * @return
	 */
	@Bean
	public ICandleSubscriptionSource candleSubscriptionSource() {
		IBCandleSource source = new IBCandleSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBCandleSeriesSource ready to subscribe for historical Candles from IB
	 * @return
	 */
	@Bean
	public ICandleSeriesSource candleSeriesSource() {
		IBCandleSeriesSource source = new IBCandleSeriesSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBQuoteSeriesSource ready to subscribe for historical Quotes from IB (bidQuantity=askQuantity=-1)
	 * @return
	 */
	@Bean
	public IQuoteSeriesSource quoteSeriesSource() {
		IBQuoteSeriesSource source = new IBQuoteSeriesSource(ibConnection());
		return source;
	}
	@Bean
	public ITickerNewsSeriesSource tickerNewsSeriesSource() {
		RSSTickerNewsSeriesSource source = new RSSTickerNewsSeriesSource();
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBContractDetailsSource for retrieving InstrumentSpecificationDetails
	 * @return
	 */
	@Bean
	public IBContractDetailsSource contractDetailsSource(){
		IBContractDetailsSource source = new IBContractDetailsSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBMarketScanSource ready to subscribe for real-time MarketScans from IB
	 * @return
	 */
	@Bean
	public IMarketScanSubscriptionSource marketScanSubscriptionSource(){
		IBMarketScanSource source = new IBMarketScanSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an RSSTickerNewsSource ready to subscribe for real-time TickerNews from Yahoo RSS
	 * @return
	 */
	@Bean
	public ITickerNewsSubscriptionSource tickerNewsSubscriptionSource(){
		RSSTickerNewsSource source = new RSSTickerNewsSource(timeStampService());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBMarketDepthSource ready to subscribe for real-time MarketDepth from IB
	 * @return
	 */
	@Bean
	public IMarketDepthEventSubscriptionSource marketDepthEventSubscriptionSource(){
		IBMarketDepthEventSource source = new IBMarketDepthEventSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an IBMarketScanChangeSource ready to subscribe for real-time MarketScanChanges from IB
	 * @return
	 */
	@Bean
	public IMarketScanChangeSubscriptionSource marketScanChangeSubscriptionSource(){
		IBMarketScanChangeSource source = new IBMarketScanChangeSource(ibConnection());
		return source;
	}
	/**
	 * Bean<br/>
	 * Creates and returns an ITradeSystemContextThread whose job is to sleep forever (just to keep the program running)
	 * @return
	 */
	@Bean 
	public ITradeSystemContextThread main() {
		return new ITradeSystemContextThread() { public void run() {
			try {
				Thread.sleep(Long.MAX_VALUE);
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}};
	}
	/**
	 * Bean<br/>
	 * Creates and returns a new SpringTradeSystemContext
	 * @return
	 */
	@Bean
	public ITradeSystemContext context() {
		return new SpringTradeSystemContext();
	}
	/**
	 * Bean<br/>
	 * Creates and returns an ITimeStampService instance whose <code>currentTimeStamp()</code> method returns the current time
	 * @return
	 */
	@Bean
	public ITimeStampService timeStampService() {

		return new ITimeStampService() {
			public TimeStamp currentTimeStamp() {
				return new TimeStamp();
			}
		};
	}
}
